import { Injectable } from '@nestjs/common';
import { isNil } from 'lodash';
import { GoodCategoryEntity, GoodEntity } from '../entities';
import { In, Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { CommonService } from '@/modules/core/base/common.service';
import { CreateGoodDto } from '../dto/create_good.dto';
import { MediaService } from '@/modules/media/services';
import { FilterGoods } from '../dto/filter_good.dto';

@Injectable()
export class GoodService {
  constructor(
    @InjectRepository(GoodEntity)
    private readonly goodRepository: Repository<GoodEntity>,
    @InjectRepository(GoodCategoryEntity)
    private readonly goodCategoryRepository: Repository<GoodCategoryEntity>,
    private readonly commonService: CommonService,
    private readonly mediaService: MediaService,
  ) {}

  async list(options: FilterGoods) {
    const { withTrash, onlyTrash, category, name } = options;
    let qb = this.goodRepository
      .createQueryBuilder('good')
      .leftJoinAndSelect('good.categories', 'categories')
      .leftJoinAndSelect('good.media', 'media')
      .leftJoinAndSelect('good.mediaIcon', 'mediaIcon');
    if (withTrash) {
      qb = qb.withDeleted();
      if (onlyTrash) qb = qb.andWhere('good.deleteAt IS NOT NULL');
    }
    if (category) {
      qb = qb.where('categories.id = :category', { category });
    }
    let goods = await qb.orderBy('good.createdAt', 'DESC').getMany();

    let filterGood;
    if (!isNil(name)) {
      filterGood = goods.filter((good) => good.name.includes(name));
      if (filterGood.length === 0) {
        goods = goods.filter((good) => {
          for (let i = 0; i < good.categories.length; i++) {
            const value = good.categories[i];
            if (value.name === name) {
              return true;
            }
          }
        });
      } else {
        goods = filterGood;
      }
    }

    return this.commonService.pagination(goods, options);
  }

  async create(body: CreateGoodDto) {
    const good = this.goodRepository.create();
    const media = await this.mediaService.detail(body.media);
    const mediaIcon = await this.mediaService.detail(body.mediaIcon);
    const categories = await this.goodCategoryRepository.find({
      where: {
        id: In(body.categories),
      },
    });
    good.name = body.name;
    good.price = body.price;
    good.description = body.description;
    good.categories = categories;
    good.oldPrice = body.oldPrice || 0;
    good.media = media;
    good.mediaIcon = mediaIcon;
    good.keywords = body.keywords || [];
    return await this.goodRepository.save(good);
  }

  async detail(id: string) {
    return await this.goodRepository.findOneOrFail({
      where: {
        id,
      },
      relations: ['categories', 'media', 'mediaIcon'],
    });
  }
  async delete(id: string) {
    const good = await this.detail(id);
    return await this.goodRepository.remove(good);
  }

  async update(id: string, body: CreateGoodDto) {
    if (!id) {
      return {
        message: 'id不能为空',
        statusCode: 400,
      };
    }
    const good = await this.detail(id);
    const categories = await this.goodCategoryRepository.find({
      where: {
        id: In(body.categories),
      },
    });
    good.name = body.name;
    good.price = body.price;
    good.description = body.description;
    good.categories = categories;
    good.oldPrice = body.oldPrice || 0;
    return await good.save();
  }
}
